package com.zshy.base.kit.date;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.zshy.base.core.contract.exception.ServiceException;
import com.zshy.base.kit.constant.DatePatternConstants;
import com.zshy.base.kit.lang.StrPoolUtils;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * LocalDate 和 LocalDateTime操作的工具类
 * JDK 1.8 时间线程安全，api丰富，不需要包装过多的工具类操作，很多操作自带了。
 * LocalDate or LocalDateTime 自带的 api：
 * <pre>
 *     now() 获取当前时间
 *     parse(时间) 根据 format 将字符串时间转换为 LocalDate or LocalDateTime
 *     format(format) 根据 format 将 LocalDate or LocalDateTime 转换为字符串时间
 *     isBefore 当前时间在另一个时间之前
 *     isAfter 当前时间在另一个时间之后
 *     compareTo 比较两个时间的大小 -1 当前时间小于另一个时间；0 相等；1 当前时间大于另一个时间；
 *     isEqual 比较两个时间是否相等
 *     minusDays 获取N天前的时间；获取N天后的时间为 plusDays；
 *     minusWeeks 获取N周前的时间； 获取N天后的时间为 plusWeeks；
 *     minusMonths 获取N月前的时间； 获取N天后的时间为 plusMonths；
 *     minusYears 获取N年前的时间；获取N天后的时间为 plusYears；
 *     Duration.between(date1, date2) 两个时间之间的操作，可以获取相差几天、小时、分钟、毫秒、纳秒
 *     getDay、getDayOfWeek、getDayOfMonth、getDayOfYear、getMonth、getYear 获取当前时间的年月日周
 *     toInstant(时区 ZoneOffset.of("+8") ).toEpochMilli() 时间戳，毫秒级，需要时区，
 *     toEpochSecond(时区 ZoneOffset.of("+8") )时间戳，秒级，需要时区，
 *     LocalDate.toString() 结果为 yyyy-MM-dd；LocalDateTime.toString() 结果为 yyyy-MM-ddTHH:mm:ss 的时间字符串
 * </pre>
 *
 * @author zhouhengzhe
 */
public class DateKit extends DateUtil {

    /**
     * 时间戳纳秒级别
     */
    private static final long REFERENCE_NANO_TIME = System.nanoTime();
    /**
     * 时间戳毫秒级别
     */
    private static final long reference_Milli_Time = System.currentTimeMillis();
    /**
     * 无符号分隔的时分秒时间格式 HHmmss
     */
    public static final DateTimeFormatter TIME_FORMAT1 = DateTimeFormatter.ofPattern(DatePattern.PURE_TIME_PATTERN);
    /**
     * “ : ” 符号分隔的时分秒时间格式 HH:mm:ss
     */
    public static final DateTimeFormatter TIME_FORMAT2 = DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN);
    /**
     * 无符号分隔的年月时间格式 yyyyMM
     */
    public static final DateTimeFormatter DATE_FORMAT1 = DateTimeFormatter.ofPattern(DatePattern.SIMPLE_MONTH_PATTERN);
    /**
     * 无符号分隔的年月日时间格式 yyyyMMdd
     */
    public static final DateTimeFormatter DATE_FORMAT2 = DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN);
    /**
     * “ - ” 符号分隔的年月时间格式 yyyy-MM
     */
    public static final DateTimeFormatter DATE_FORMAT3 = DateTimeFormatter.ofPattern(DatePattern.NORM_MONTH_PATTERN);
    /**
     * “ - ” 符号分隔的年月日时间格式 yyyy-MM-dd
     */
    public static final DateTimeFormatter DATE_FORMAT4 = DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN);
    /**
     * “ / ” 符号分隔的年月时间格式 yyyy/MM
     */
    public static final DateTimeFormatter DATE_FORMAT5 = DateTimeFormatter.ofPattern(DatePatternConstants.EN_DATE_MONTH_PATTERN);
    /**
     * “ / ” 符号分隔的年月日时间格式 yyyy/MM/dd
     */
    public static final DateTimeFormatter DATE_FORMAT6 = DateTimeFormatter.ofPattern(DatePatternConstants.EN_DATE_PATTERN);
    /**
     * “ / ” 符号分隔的月日年时间格式 MM/dd/yyyy
     */
    public static final DateTimeFormatter DATE_FORMAT7 = DateTimeFormatter.ofPattern(DatePatternConstants.ZH_DATE_PATTERN);

    /**
     * 无符号分隔的年月日时分秒时间格式 yyyyMMddHHmmss
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT1 = DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN);
    /**
     * 无符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyyMMdd HH:mm:ss
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT2 = DateTimeFormatter.ofPattern(DatePatternConstants.DATE_TIME_FORMAT2);
    /**
     * “ - ” 符号分隔的年月日 “ : ” 符号分隔的时分时间格式 yyyy-MM-dd HH:mm
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT3 = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_MINUTE_PATTERN);
    /**
     * “ - ” 符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyy-MM-dd HH:mm:ss
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT4 = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
    /**
     * “ / ” 符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyy/MM/dd HH:mm:ss
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT5 = DateTimeFormatter.ofPattern(DatePatternConstants.EN_DATETIME_PATTERN);
    /**
     * 标准的 ISO 年月日时分秒时间格式 yyyy-MM-dd'T'HH:mm:ss
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT6 = DateTimeFormatter.ofPattern(DatePattern.UTC_SIMPLE_PATTERN);
    /**
     * 标准的 ISO 年月日时分秒时间格式 yyyy-MM-dd HH:mm:ss.S
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT7 = DateTimeFormatter.ofPattern(DatePatternConstants.DATE_TIME_FORMAT7);
    /**
     * “ - ” 符号分隔的年月日 “ : ” 符号分隔的时分秒毫秒时间格式 yyyy-MM-dd HH:mm:ss.SSS
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT8 = DateTimeFormatter.ofPattern(DatePatternConstants.DATE_TIME_FORMAT8);
    /**
     * 标准的 ISO 年月日时分秒毫秒时间格式 yyyy-MM-dd'T'HH:mm:ss.SSS
     */
    public static final DateTimeFormatter DATE_TIME_FORMAT9 = DateTimeFormatter.ofPattern(DatePattern.UTC_SIMPLE_MS_PATTERN);

    private static final ThreadLocal<Map<String, SimpleDateFormat>> threadLocal = ThreadLocal.withInitial(HashMap::new);

    /**
     * 将字符串转换为日期对象
     *
     * @param dateStr 待转换的日期字符串
     * @param pattern 日期格式，例如：yyyy-MM-dd HH:mm:ss
     * @return 转换后的日期对象
     * @throws ServiceException 如果转换过程中出现错误，则抛出该异常
     * @see DatePatternConstants pattern值可以从当前常量类获取
     */
    public static Date stringToDate(String dateStr, String pattern) {
        checkParam(dateStr, pattern);
        Map<String, SimpleDateFormat> formatMap = threadLocal.get();
        SimpleDateFormat sdf = formatMap.get(pattern);
        if (sdf == null) {
            sdf = new SimpleDateFormat(pattern);
            formatMap.put(pattern, sdf);
        }
        try {
            // 尝试将字符串解析为日期对象
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new ServiceException(e);
        }
    }

    /**
     * 检查参数
     *
     * @param dateStr 待转换的日期字符串
     * @param pattern 转换后的日期格式，例如：yyyy-MM-dd HH:mm:ss
     * @see DatePatternConstants pattern值可以从当前常量类获取
     */
    private static void checkParam(Object dateStr, String pattern) {
        if (dateStr == null) {
            throw new IllegalArgumentException("dateStr cannot be null.");
        }
        if (pattern == null || pattern.trim().isEmpty()) {
            throw new IllegalArgumentException("Pattern cannot be null or empty.");
        }
    }

    /**
     * 获取指定格式的当前时间
     *
     * @param pattern 日期格式字符串，如"yyyy-MM-dd HH:mm:ss"
     * @return 返回一个Date对象，表示当前时间
     * @see DatePatternConstants pattern值可以从当前常量类获取
     */
    public static Date getCurrentDate(String pattern) {
        if (pattern == null || pattern.trim().isEmpty()) {
            throw new IllegalArgumentException("Pattern cannot be null or empty.");
        }
        return stringToDate(dateToString(new Date(), pattern), pattern);
    }

    /**
     * 将日期对象转换为指定格式的字符串
     *
     * @param date    待转换的日期对象，不能为空
     * @param pattern 转换后的日期格式，例如"yyyy-MM-dd HH:mm:ss"
     * @return 转换后的日期字符串
     * @see DatePatternConstants pattern值可以从当前常量类获取
     */
    public static String dateToString(Date date, String pattern) {
        checkParam(date, pattern);
        Map<String, SimpleDateFormat> formatMap = threadLocal.get();
        SimpleDateFormat sdf = formatMap.get(pattern);
        if (sdf == null) {
            sdf = new SimpleDateFormat(pattern);
            formatMap.put(pattern, sdf);
        }
        return sdf.format(date);
    }

    /**
     * 比较两个日期的大小
     *
     * @param date1 第一个日期
     * @param date2 第二个日期
     * @return 如果date1在date2之前，返回-1；如果date1和date2相等，返回0；如果date1在date2之后，返回1
     */
    public static int compareDate(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("Dates cannot be null");
        }
        return date1.compareTo(date2);
    }

    /**
     * 将LocalDate类型按指定格式转换为Date类型
     *
     * @param localDate 要转换的LocalDate对象
     * @param pattern   日期格式，例如"yyyy-MM-dd"
     * @return 转换后的Date对象
     * @throws IllegalArgumentException 如果转换过程中发生异常，则抛出该异常
     * @see DatePatternConstants pattern值可以从当前常量类获取
     */
    public static Date localDateToDate(LocalDate localDate, String pattern) {
        Objects.requireNonNull(localDate, "localDate must not be null");
        Objects.requireNonNull(pattern, "Pattern must not be null");
        return stringToDate(localDate.format(DateTimeFormatter.ofPattern(pattern)), pattern);
    }

    /**
     * 根据传入的时间格式格式化字符串并返回LocalDate类型
     *
     * @param dateStr           时间格式的字符串，不可为空
     * @param dateTimeFormatter 格式化模板，不可为空
     * @return 格式化后的LocalDate对象
     * @throws DateTimeParseException 如果日期字符串与格式化模板不匹配，则抛出此异常
     * @see DatePatternConstants dateStr值可以从当前常量类获取
     */
    public static LocalDate parseLocalDate(String dateStr, DateTimeFormatter dateTimeFormatter) {
        Objects.requireNonNull(dateStr, "dateStr must not be null");
        Objects.requireNonNull(dateTimeFormatter, "dateTimeFormatter must not be null");
        return LocalDate.parse(dateStr, dateTimeFormatter);
    }

    /**
     * 根据传入的时间格式字符串和格式化模板，将时间格式字符串转换为LocalDateTime对象
     *
     * @param dateStr           待转换的时间格式字符串，例如："2022-03-14T15:30:00"
     * @param dateTimeFormatter 格式化模板，例如：DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
     * @return 转换后的LocalDateTime对象
     * @throws DateTimeParseException 如果转换失败，则抛出DateTimeParseException异常
     * @see DatePatternConstants dateStr值可以从当前常量类获取
     */
    public static LocalDateTime parseLocalDateTime(String dateStr, DateTimeFormatter dateTimeFormatter) {
        if (dateStr == null || dateTimeFormatter == null) {
            throw new NullPointerException("dateStr and dateTimeFormatter must not be null");
        }
        return LocalDateTime.parse(dateStr, dateTimeFormatter);
    }

    /**
     * 将LocalDate对象转换为指定格式的字符串
     *
     * @param localDate         需要转换的LocalDate对象
     * @param dateTimeFormatter 日期时间格式化模板
     * @return 转换后的字符串
     */
    public static String localDateToStr(LocalDate localDate, DateTimeFormatter dateTimeFormatter) {
        if (localDate == null || dateTimeFormatter == null) {
            // 根据实际需求，可以选择返回null或抛出异常
            // throw new IllegalArgumentException("Parameters cannot be null");
            return null;
        }
        return localDate.format(dateTimeFormatter);
    }

    /**
     * 将LocalDateTime转换为指定格式的字符串。
     * 注意：该方法不限制具体的时间格式，而是依赖于传入的DateTimeFormatter来确定输出格式。
     *
     * @param localDateTime     待转换的LocalDateTime对象，可以为null
     * @param dateTimeFormatter 时间格式模板，用于指定转换后的字符串格式，不能为空
     * @return 转换后的字符串，如果localDateTime为null或dateTimeFormatter为null，则返回null
     */
    public static String localDateTimeToStr(LocalDateTime localDateTime, DateTimeFormatter dateTimeFormatter) {
        if (localDateTime == null || dateTimeFormatter == null) {
            return null;
        }
        return localDateTime.format(dateTimeFormatter);
    }

    /**
     * 将时间格式的字符串转换成 LocalDate。
     * 支持的标准时间格式为：yyyyMMdd、yyyy-MM-dd、yyyy/MM/dd、yyyyMMddHHmmss、yyyy-MM-dd HH:mm:ss、yyyy/MM/dd HH:mm:ss
     *
     * @param dateStr 时间格式的字符串，不能为空
     * @return 转换后的LocalDate，如果转换失败则返回null
     */
    public static LocalDate parseLocalDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        LocalDate localDate;
        // “ - ” 符号分隔的年月日时间格式
        if (dateStr.contains(StrPoolUtils.DASH)) {
            if (dateStr.contains(StringUtils.SPACE)) {
                return LocalDateTime.parse(dateStr, DATE_TIME_FORMAT4).toLocalDate();
            }
            return LocalDate.parse(dateStr, DATE_FORMAT4);
            // “ / ” 符号分隔的年月日时间格式
        } else if (dateStr.contains(StrPoolUtils.SLASH)) {
            if (dateStr.contains(StringUtils.SPACE)) {
                return LocalDateTime.parse(dateStr, DATE_TIME_FORMAT5).toLocalDate();
            }
            return LocalDate.parse(dateStr, DATE_FORMAT6);
            // 无符号分隔的年月日时间格式
        } else {
            if (dateStr.length() == 14) {
                return LocalDateTime.parse(dateStr, DATE_TIME_FORMAT1).toLocalDate();
            }
            return LocalDate.parse(dateStr, DATE_FORMAT2);
        }
    }

    /**
     * 将时间格式的字符串转换成 LocalDateTime 对象。
     * 支持的标准时间格式为：
     * yyyyMMdd、yyyy-MM-dd、yyyy/MM/dd、yyyyMMddHHmmss、yyyy-MM-dd HH:mm:ss、yyyy/MM/dd HH:mm:ss
     * 以及 yyyy-MM-dd'T'HH:mm:ss 格式（用于处理 ISO 8601 格式的日期时间字符串）。
     *
     * @param dateTimeStr 时间格式的字符串，用于转换的源数据
     * @return 转换后的 LocalDateTime 对象，如果转换失败则返回 null
     */
    public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
        if (StringUtils.isEmpty(dateTimeStr)) {
            return null;
        }
        LocalDateTime localDateTime;
        // “ - ” 符号分隔的年月日时间格式
        if (dateTimeStr.contains(StrPoolUtils.DASH)) {
            if (dateTimeStr.contains(StringUtils.SPACE)) {
                return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMAT4);
            } else if (dateTimeStr.contains("T")) {
                return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMAT6);
            } else {
                return LocalDate.parse(dateTimeStr, DATE_FORMAT4).atStartOfDay();
            }
            // “ / ” 符号分隔的年月日时间格式
        } else if (dateTimeStr.contains(StrPoolUtils.SLASH)) {
            if (dateTimeStr.contains(StringUtils.SPACE)) {
                return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMAT5);
            }
            return LocalDate.parse(dateTimeStr, DATE_FORMAT6).atStartOfDay();
            // 无符号分隔的年月日时间格式
        } else {
            if (dateTimeStr.length() == 8) {
                return LocalDate.parse(dateTimeStr, DATE_FORMAT2).atStartOfDay();
            }
            return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMAT1);

        }
    }

    /**
     * 获取无符号分隔的年月日时间格式 yyyyMMdd 的字符串表示形式。
     *
     * @param localDate 要转换的 LocalDate 对象
     * @return 转换后的字符串表示形式，如果转换失败则返回 null
     */
    public static String getDateFormat2Str(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateToStr(localDate, DATE_FORMAT2);
    }

    /**
     * 获取当前无符号分隔的年月日时间格式 yyyyMMdd 的字符串表示形式。
     *
     * @return 返回当前无符号分隔的年月日时间格式 yyyyMMdd 的字符串表示形式
     */
    public static String getDateFormat2Str() {
        return localDateToStr(LocalDate.now(), DATE_FORMAT2);
    }

    /**
     * 获取当前无符号分隔的时分秒时间格式 HHmmss 的字符串表示形式。
     *
     * @return 当前无符号分隔的时分秒时间格式 HHmmss 的字符串表示形式
     */
    public static String getTimeFormat1Str() {
        return localDateTimeToStr(LocalDateTime.now(), TIME_FORMAT1);
    }

    /**
     * 将给定的LocalDateTime对象转换为无符号分隔的时分秒时间格式 HHmmss的字符串表示形式。
     *
     * @param localDateTime 待转换的LocalDateTime对象
     * @return 转换后的无符号分隔的时分秒时间格式 HHmmss的字符串表示形式
     */
    public static String getTimeFormat1Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, TIME_FORMAT1);
    }

    /**
     * 获取当前使用“ : ”符号分隔的时分秒时间格式 HH:mm:ss 的字符串表示形式。
     *
     * @return 当前使用“ : ”符号分隔的时分秒时间格式 HH:mm:ss 的字符串表示形式
     */
    public static String getTimeFormat2Str() {
        return localDateTimeToStr(LocalDateTime.now(), TIME_FORMAT2);
    }

    /**
     * 将给定的LocalDateTime对象转换为使用“ : ”符号分隔的时分秒时间格式 HH:mm:ss 的字符串表示形式。
     *
     * @param localDateTime 待转换的LocalDateTime对象
     * @return 转换后的使用“ : ”符号分隔的时分秒时间格式 HH:mm:ss 的字符串表示形式
     */
    public static String getTimeFormat2Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, TIME_FORMAT2);
    }

    /**
     * 获取当前无符号分隔的年月日时分秒时间格式 yyyyMMddHHmmss 的字符串表示形式。
     *
     * @return 当前无符号分隔的年月日时分秒时间格式 yyyyMMddHHmmss 的字符串表示形式
     */
    public static String getDateTimeFormat1Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT1);
    }

    /**
     * 获取指定无符号分隔的年月日时分秒时间格式 yyyyMMddHHmmss 的字符串表示形式。
     *
     * @param localDateTime 待转换的LocalDateTime对象
     * @return 转换后的无符号分隔的年月日时分秒时间格式 yyyyMMddHHmmss 的字符串表示形式
     */
    public static String getDateTimeFormat1Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT1);
    }

    /**
     * 获取当前使用“ - ”符号分隔的年月时间格式 yyyy-MM 的字符串表示形式。
     *
     * @return 当前使用“ - ”符号分隔的年月时间格式 yyyy-MM 的字符串表示形式
     */
    public static String getDateFormat3Str() {
        return localDateToStr(LocalDate.now(), DATE_FORMAT3);
    }

    /**
     * 将给定的LocalDate对象转换为使用“ - ”符号分隔的年月时间格式 yyyy-MM 的字符串表示形式。
     *
     * @param localDate 要转换的LocalDate对象
     * @return 转换后的字符串表示形式
     */
    public static String getDateFormat3Str(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateToStr(localDate, DATE_FORMAT3);
    }

    /**
     * 获取当前使用“ - ”符号分隔的年月日时间格式 yyyy-MM-dd 的字符串表示形式。
     *
     * @return 当前使用“ - ”符号分隔的年月日时间格式 yyyy-MM-dd 的字符串表示形式
     */
    public static String getDateFormat4Str() {
        return localDateToStr(LocalDate.now(), DATE_FORMAT4);
    }

    /**
     * 获取指定LocalDate对象使用“ - ”符号分隔的年月日时间格式 yyyy-MM-dd 的字符串表示形式。
     *
     * @param localDate 要转换的LocalDate对象
     * @return 转换后的字符串表示形式
     */
    public static String getDateFormat4Str(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateToStr(localDate, DATE_FORMAT4);
    }

    /**
     * 获取当前“ - ”符号分隔的年月日与“ : ”符号分隔的时分秒时间格式 yyyy-MM-dd HH:mm:ss 的字符串表示形式。
     *
     * @return 返回当前时间的字符串表示形式，格式为 yyyy-MM-dd HH:mm:ss
     */
    public static String getDateTimeFormat4Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT4);
    }

    /**
     * 将给定的LocalDateTime对象转换为使用“ - ”符号分隔的年月日与“ : ”符号分隔的时分秒时间格式 yyyy-MM-dd HH:mm:ss 的字符串表示形式。
     *
     * @param localDateTime 要转换的LocalDateTime对象
     * @return 转换后的字符串表示形式
     */
    public static String getDateTimeFormat4Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT4);
    }

    /**
     * 获取当前标准的 ISO 年月日时分秒时间格式，格式为 yyyy-MM-dd'T'HH:mm:ss。
     *
     * @return 返回当前时间的字符串表示形式，格式为 yyyy-MM-dd'T'HH:mm:ss
     */
    public static String getDateTimeFormat6Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT6);
    }

    /**
     * 将给定的 LocalDateTime 对象转换为标准的 ISO 年月日时分秒时间格式的字符串。
     *
     * @param localDateTime 待转换的 LocalDateTime 对象
     * @return 转换后的字符串，格式为 yyyy-MM-dd'T'HH:mm:ss
     */
    public static String getDateTimeFormat6Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT6);
    }

    /**
     * 获取当前无符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyyMMdd HH:mm:ss 的字符串表示形式。
     *
     * @return 返回当前无符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyyMMdd HH:mm:ss 的字符串表示形式
     */
    public static String getDateTimeFormat2Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT2);
    }

    /**
     * 将指定的 LocalDateTime 对象转换为无符号分隔的年月日 “ : ” 符号分隔的时分秒时间格式 yyyyMMdd HH:mm:ss 的字符串表示形式。
     *
     * @param localDateTime 待转换的 LocalDateTime 对象
     * @return 转换后的字符串表示形式
     */
    public static String getDateTimeFormat2Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT2);
    }

    /**
     * 获取当前使用“ / ”符号分隔的月日年时间格式 MM/dd/yyyy 的字符串表示形式。
     *
     * @return 当前使用“ / ”符号分隔的月日年时间格式 MM/dd/yyyy 的字符串表示形式
     */
    public static String getDateFormat7Str() {
        return localDateToStr(LocalDate.now(), DATE_FORMAT7);
    }

    /**
     * 将LocalDate对象转换为“ / ”符号分隔的月日年时间格式MM/dd/yyyy的字符串表示形式。
     *
     * @param localDate 待转换的LocalDate对象
     * @return 转换后的字符串表示形式
     */
    public static String getDateFormat7Str(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateToStr(localDate, DATE_FORMAT7);
    }

    /**
     * 获取当前使用“ - ”符号分隔的年月日与“ : ”符号分隔的时分秒毫秒时间格式 yyyy-MM-dd HH:mm:ss.SSS 的字符串表示形式。
     *
     * @return 当前时间的字符串表示形式，格式为 yyyy-MM-dd HH:mm:ss.SSS
     */
    public static String getDateTimeFormat8Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT8);
    }

    /**
     * 将指定的 LocalDateTime 对象转换为 " - " 符号分隔的年月日 " : " 符号分隔的时分秒毫秒时间格式 yyyy-MM-dd HH:mm:ss.SSS 的字符串表示形式。
     *
     * @param localDateTime 当前时间
     * @return 转换后的字符串表示形式
     */
    public static String getDateTimeFormat8Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT8);
    }

    /**
     * 获取当前标准的 ISO 年月日时分秒毫秒时间格式字符串。
     * 格式为：yyyy-MM-dd'T'HH:mm:ss.SSS。
     *
     * @return 当前时间的字符串表示形式，格式为 yyyy-MM-dd'T'HH:mm:ss.SSS
     */
    public static String getDateTimeFormat9Str() {
        return localDateTimeToStr(LocalDateTime.now(), DATE_TIME_FORMAT9);
    }

    /**
     * 将指定的 LocalDateTime 对象转换为标准的 ISO 年月日时分秒毫秒时间格式 yyyy-MM-dd'T'HH:mm:ss.SSS 的字符串表示形式。
     *
     * @param localDateTime 当前时间
     * @return 转换后的字符串表示形式
     */
    public static String getDateTimeFormat9Str(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDateTimeToStr(localDateTime, DATE_TIME_FORMAT9);
    }

    /**
     * 获取当前时间的本周一
     *
     * @param localDate 当前时间
     * @return 返回本周一的LocalDate对象
     */
    public static LocalDate getWeekMonday(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDate.with(DayOfWeek.MONDAY);
    }

    /**
     * 获取给定时间的本月最后一天。
     *
     * @param localDate 给定的时间
     * @return 返回本月最后一天的日期
     */
    public static LocalDate getLastDayOfMonth(LocalDate localDate) {
        if (localDate == null) {
            // 明确处理 null 情况，增强代码的健壮性
            return null;
        }
        return localDate.with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 检查当前时间是否在给定的时间范围内
     *
     * @param scopeTime   时间范围，格式为 HH:mm:ss-HH:mm:ss
     * @param compareTime 待比较的时间
     * @return 如果在给定的时间范围内返回true，否则返回false
     */
    public static boolean isInScopeTime(String scopeTime, LocalDateTime compareTime) {
        String[] split = scopeTime.split("-");
        if (split.length != 2) {
            throw new IllegalArgumentException("Invalid scopeTime format. Expected format: HH:mm:ss-HH:mm:ss");
        }
        String nowDate = compareTime.toLocalDate().toString();
        LocalDateTime startTime = DateKit.parseLocalDateTime(nowDate + " " + split[0]);
        LocalDateTime endTime = DateKit.parseLocalDateTime(nowDate + " " + split[1]);
        // 是否在时间范围内
        return compareTime.isAfter(startTime) && compareTime.isBefore(endTime);
    }

    /**
     * 返回一个序列化的日期时间字符串，格式为yyyyMMdd。
     *
     * @return 序列化后的日期时间字符串
     */
    public static String formatPacked() {
        // 直接获取当前日期时间
        LocalDateTime dateTime = LocalDateTime.now(ZoneId.systemDefault());
        // 格式化日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        return dateTime.format(formatter);
    }

    /**
     * 将LocalDateTime对象转换为Date对象
     *
     * @param localDateTime 要转换的LocalDateTime对象，如果为null则返回null
     * @return 转换后的Date对象，如果localDateTime为null则返回null
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return localDateTime == null ? null : Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将LocalDateTime对象转换为Date对象,可指定时区
     *
     * @param localDateTime 要转换的LocalDateTime对象，如果为null则返回null
     * @param zoneId        时区ID，用于转换LocalDateTime到Instant
     * @return 转换后的Date对象，如果localDateTime为null则返回null
     */
    public static Date toDate(LocalDateTime localDateTime, ZoneId zoneId) {
        if (localDateTime == null) {
            return null;
        }
        return Date.from(localDateTime.atZone(zoneId != null ? zoneId : ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将Date类型转换为LocalDateTime类型
     *
     * @param date 要转换的Date类型时间
     * @return 转换后的LocalDateTime类型时间，如果传入的Date为null则返回null
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return date == null ? null : date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 将给定的java.util.Date类型转换为java.time.LocalDate类型
     *
     * @param date 待转换的java.util.Date类型对象
     * @return 转换后的java.time.LocalDate类型对象，如果date为null则返回null
     */
    public static LocalDate toLocalDate(Date date) {
        if (date == null) {
            return null;
        }
        //用ZoneId.systemDefault()可能会在不同的系统或不同的运行时刻产生不同的结果，因为系统默认时区可能会变化
        //比如在中国就是Asia/Shanghai
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().toLocalDate();
    }

    /**
     * 计算距离今天结束还有多少秒数
     *
     * @return 返回距离今天结束还有多少秒数的长整型数值
     */
    public static long secondsUntilEndOfDay() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime todayEnd = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);
        if (now.isAfter(todayEnd)) {
            // 如果当前时间已经超过今天的结束时间，则计算到下一天的结束时间
            todayEnd = todayEnd.plusDays(1);
        }
        return ChronoUnit.SECONDS.between(now, todayEnd);
    }
}
